package com.example.demo.Shiro.config;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.example.demo.Shiro.entity.User;
import com.example.demo.Shiro.service.IUserRoleService;
import com.example.demo.Shiro.service.IUserService;
import com.example.demo.Shiro.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.context.WebApplicationContext;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ShiroRealm extends AuthorizingRealm {
    @Resource
    private IUserService iUserService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //用户登录次数计数  redisKey 前缀
    private String SHIRO_LOGIN_COUNT = "shiro_login_count_";

    //用户登录是否被锁定    一小时 redisKey 前缀
    private String SHIRO_IS_LOCK = "shiro_is_lock_";


    //用户认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //authenticationToken为用户输入信息
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        String username = (String)authenticationToken.getPrincipal();
        String password = String.valueOf(token.getPassword());
        User user = iUserService.findOneByUserName(username);
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        //MD5密码加密
        String salt = String.valueOf(user.getUsername());
        SimpleHash hash = new SimpleHash("md5", password, salt);
        String encodedPassword = hash.toHex();
        if (user == null){
            log.info("不存在此用户");
            throw new UnknownAccountException();//没找到帐号
        }
        //访问一次，计数一次
        opsForValue.increment(SHIRO_LOGIN_COUNT + username, 1);
        //计数大于5时，设置用户被锁定
        if(Integer.parseInt(opsForValue.get(SHIRO_LOGIN_COUNT + username))>=5){
            opsForValue.set(SHIRO_IS_LOCK + username, "LOCK");
            stringRedisTemplate.expire(SHIRO_IS_LOCK + username, 2, TimeUnit.MINUTES);
            stringRedisTemplate.expire(SHIRO_LOGIN_COUNT + username, 2, TimeUnit.MINUTES);
        }
        if ("LOCK".equals(opsForValue.get(SHIRO_IS_LOCK+username))){
            throw new DisabledAccountException();
        }
        if (!encodedPassword.equals(user.getPassword())){
            log.info("密码错误");
            throw new IncorrectCredentialsException();
        }
        //清空登录计数
        opsForValue.set(SHIRO_LOGIN_COUNT + username, "0");
        opsForValue.set(SHIRO_IS_LOCK+username, "UNLOCK");
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, user.getId() + "");
        return info;
    }

    //用户授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authenticationInfo = new SimpleAuthorizationInfo();
        return null;
    }

    //登录错误重试设置

}
